<?php
/**
 * @author 595949289@qq.com
 * @date 2023/9/6 11:32
 */

namespace CuiFox\oauth2server;

use filsh\yii2\oauth2server\traits\ClassNamespace;
use OAuth2\RequestInterface;
use OAuth2\ResponseInterface;
use OAuth2\TokenType\TokenTypeInterface;
use OAuth2\ScopeInterface;
use OAuth2\ClientAssertionType\ClientAssertionTypeInterface;

class Server extends \OAuth2\Server
{
    use ClassNamespace;

    /**
     * @var Module
     */
    protected $module;

    /**
     * Server constructor.
     * @param Module $module
     * @param array $storage
     * @param array $config
     * @param array $grantTypes
     * @param array $responseTypes
     * @param TokenTypeInterface|null $tokenType
     * @param ScopeInterface|null $scopeUtil
     * @param ClientAssertionTypeInterface|null $clientAssertionType
     */
    public function __construct(
        Module $module,
        $storage = [],
        array $config = [],
        array $grantTypes = [],
        array $responseTypes = [],
        TokenTypeInterface $tokenType = null,
        ScopeInterface $scopeUtil = null,
        ClientAssertionTypeInterface $clientAssertionType = null
    ) {
        parent::__construct($storage, $config, $grantTypes, $responseTypes, $tokenType, $scopeUtil,
            $clientAssertionType);

        $this->module = $module;
    }

    /**
     * @param $clientId
     * @param $userId
     * @param null $scope
     * @param bool $includeRefreshToken
     * @return array
     */
    public function createAccessToken($clientId, $userId, $scope = null, $includeRefreshToken = true)
    {
        $accessToken = $this->getAccessTokenResponseType();
        return $accessToken->createAccessToken($clientId, $userId, $scope, $includeRefreshToken);
    }

    /**
     * @param RequestInterface|null $request
     * @param ResponseInterface|null $response
     * @param null $scope
     * @return mixed
     */
    public function verifyResourceRequest(
        RequestInterface $request = null,
        ResponseInterface $response = null,
        $scope = null
    ) {
        if ($request === null) {
            $request = $this->module->getRequest();
        }
        return parent::verifyResourceRequest($request, $response, $scope);
    }

    /**
     * @param RequestInterface|null $request
     * @param ResponseInterface|null $response
     * @return mixed
     */
    public function getAccessTokenData(RequestInterface $request = null, ResponseInterface $response = null)
    {
        if ($request === null) {
            $request = $this->module->getRequest();
        }
        return parent::getAccessTokenData($request, $response);
    }

    /**
     * @param RequestInterface|null $request
     * @param ResponseInterface|null $response
     * @return ResponseInterface
     */
    public function handleTokenRequest(RequestInterface $request = null, ResponseInterface $response = null)
    {
        if ($request === null) {
            $request = $this->module->getRequest();
        }
        return parent::handleTokenRequest($request, $response);
    }

    /**
     * @param RequestInterface|null $request
     * @param ResponseInterface|null $response
     * @return \OAuth2\Response|ResponseInterface
     */
    public function handleRevokeRequest(RequestInterface $request = null, ResponseInterface $response = null)
    {
        if ($request === null) {
            $request = $this->module->getRequest();
        }
        return parent::handleRevokeRequest($request, $response);
    }

    /**
     * @param RequestInterface|null $request
     * @param ResponseInterface|null $response
     * @param bool $isAuthorized
     * @param null $userId
     * @return ResponseInterface
     * @throws \yii\base\InvalidConfigException
     */
    public function handleAuthorizeRequest(
        RequestInterface $request = null,
        ResponseInterface $response = null,
        $isAuthorized = false,
        $userId = null
    ) {
        if ($request === null) {
            $request = $this->module->getRequest();
        }
        if ($response === null) {
            $response = $this->module->getResponse();
        }

        return parent::handleAuthorizeRequest($request, $response, $isAuthorized, $userId);
    }

    /**
     * @param RequestInterface|null $request
     * @param ResponseInterface|null $response
     * @return ResponseInterface
     */
    public function handleUserInfoRequest(RequestInterface $request = null, ResponseInterface $response = null)
    {
        if ($request === null) {
            $request = $this->module->getRequest();
        }
        return parent::handleUserInfoRequest($request, $response);
    }
}